Soru & Cevap

navigation drawer fragment altında AsyncTask

05.11.2014 - 09:50

merhabalar hocam. müsait olduğunuzda bakarsanız çok sevinirim.


navigation drawer fragment uygulaması yaptım. fragment in içinde şu kodları oluşturdum ama hemen hata verip çıkıyor.

public class WhatsHotFragment extends Fragment implements OnClickListener  {


 
Button bSorgula;
   EditText etID, etProductName, etCategoryName, etUnitPrice;

@Override
   public View onCreateView(LayoutInflater inflater,
   ViewGroup container, Bundle savedInstanceState)
   {
       View view = inflater.inflate(
           R.layout.fragment_whats_hot, container, false);
       
     
       
       bSorgula = (Button) view.findViewById(R.id.bSorgula);
       bSorgula.setOnClickListener(this);
 
       etID = (EditText) view.findViewById(R.id.etID);
       etProductName = (EditText) view.findViewById(R.id.etProductName);
       etCategoryName = (EditText) view.findViewById(R.id.etCategoryName);
       etUnitPrice = (EditText) view.findViewById(R.id.etUnitPrice);
       
       

       return view;
   }

@Override
public void onClick(View v) {

new myAsyncTask("Yükleniyor").execute();

}


private class myAsyncTask extends AsyncTask<Void, Void, Void> {
 
       String modalMesaj;
       ProgressDialog dialog;
 
       JSONObject jsonObject = null;
 
       String productName = "";
       String categoryName = "";
       String unitPrice = "";
 
       public myAsyncTask(String mMesaj) {
           this.modalMesaj = mMesaj;
         //  this.dialog = new ProgressDialog();
       }
 
       @Override
       protected void onPreExecute() {
           dialog.setMessage(modalMesaj);
           dialog.setIndeterminate(true);
           dialog.setCancelable(false);
           dialog.show();
       }
 
       @Override
       protected Void doInBackground(Void... params) {
 
           Integer productID = Integer.valueOf(etID.getText().toString());
 
           String url = "http://madenteknikerleri.net/calisma/Default.aspx?ProductId="
                   + productID;
 
           HttpClient httpclient = new DefaultHttpClient();
 
           HttpGet httpget = new HttpGet(url);
 
           HttpResponse response;
           try {
               response = httpclient.execute(httpget);
 
               HttpEntity entity = response.getEntity();
 
               if (entity != null) {
                   InputStream instream = entity.getContent();
                   String result = convertStreamToString(instream);
 
                   jsonObject = new JSONObject(result);
 
                   instream.close();
               }
 
           } catch (ClientProtocolException e) {
               Mesaj(e.getMessage());
           } catch (IOException e) {
               Mesaj(e.getMessage());
           } catch (JSONException e) {
               Mesaj(e.getMessage());
           }
 
           return null;
       }
 
       @Override
       protected void onPostExecute(Void str) {
 
           if (dialog.isShowing())
               dialog.dismiss();
 
           try {
 
               productName = jsonObject.getString("ProductName").toString();
               categoryName = jsonObject.getString("CategoryName").toString();
               unitPrice = jsonObject.getString("UnitPrice").toString();
 
               etProductName.setText(this.productName);
               etCategoryName.setText(this.categoryName);
               etUnitPrice.setText(this.unitPrice);
 
           } catch (JSONException e) {
               e.printStackTrace();
           }
 
       }
   }
    
   private static String convertStreamToString(InputStream is) {
 
       BufferedReader reader = new BufferedReader(new InputStreamReader(is));
       StringBuilder sb = new StringBuilder();
 
       String line = null;
       try {
           while ((line = reader.readLine()) != null) {
               sb.append(line + "\n");
           }
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           try {
               is.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       return sb.toString();
   }
 
   private void Mesaj(String s) {
 
       Toast.makeText(this.getActivity(), s, Toast.LENGTH_LONG).show();
   }




}

23 Görüntülenme

4 Cevap

Sitedeki sorulara cevap verebilmek için giriş yapın ya da üye olun.

picture-7494-1397646387.jpg
baranbuyuk
07.11.2014 - 01:39

AsyncTak işlemi sırasında, işlem boyunca kişiye bir dialog göstermenin yolu şöyle; 

Öncelikle TaskListener isminde bir interface tanımlayın ve bu interface in iki methodu olsun, şöyle ki;

 

[code]

public interface TaskListener {

   void onTaskStarted();

   void onTaskFinished();

}

[/code]

Daha sonra dialog penceresini göstermek istediğiniz Activiy'de bu interfaci implement edin. Bu Fragmentte olabilir. Hiç önemli değil. Siz bu interfaci implemen ettiğinizde otomatik olarak onTaskStarted ve onTaskFinished metodlarınu override etmenizi isteyecek. Bunları override edin.

Şimdi iş yapan sınıfınıza gelin. Öncelikle AsyncTask nasıl çalışır onu bilmeniz gerekiyor. Bunu bildiğinizi varsayıyorum. Çünkü ayrı bir konu. Bu sınıfı extend ettiğinizde sizden doInBackground methodunu implemente etmenizi ister. Yani, arka planda gerçekleştireceğiniz her türlü işlem burada gerçekleşir. Yalnız bu methodun çok önemli bir özelliği vardır. Bu method içerisinden mainthread e erişemesiniz. yani kullanıcı ile etkileşime giremezsiniz. bu nedenle bu method içerisinde kullanıcıya birşey gösteremez, veri alamazsınız. 

Bunun dışında onPostExecuted ve onProgressUpdate ile onPreExecuted methodları bulunmaktadır. onPreExecute methodu arka planda iş yapmaya başlamadan önce tetiklenir. Tam burada siz dialog ekranınızı göstereceksiniz. onPostExecuted methodu ise arka plandaki iş bittiğinde otomatik olarak system tarafından tetiklenir. Burada da işlem bittiği için dialog ekranını kapatacaksınız.

Şimdi nasıl yapıyoruz ona bakalım.

Yukarıda interfacimizi tanımladık ve kullanacağımız sınıfa implement ettik. Şimdi AsyncTask sınıfının default Constructur'ına (TaskListener listener) tipinde bir argüman gönderiyoruz. yine TaskListener listener şeklinde interfacemizden bir variable tanımlıuyoruz.. Daha sonra bu interface nin methodlarını kullanıyoruz. Kod aşağıdaki gibidir..

 

[code]

class MyAsycnTask extends AsyncTask<Void, Void, Void>{
    private TaskListener listener;
    public MyAsycnTask(TaskListener listener) {
        this.listener = listener;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //İşleme başlamadan bu method tetikleniyor.
        this.listener.onTaskStarted();
    }
    @Override
    protected Void doInBackground(Void... params) {
        //Burada işlemlerimizi gerçekleştiriyoruz...
        return null;
    }
    
    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        //İşlem bitince bu method tetikleniyor.
        this.listener.onTaskFinished();
    }
}

[/code]

Biz yukarıdaki kodlarla şunu yaptık. Dedik ki; Ey asynctask sınıfı sen çalışmaya başlamadan önce TaskListener interface ni implement ettiğim subclasstaki onTaskStarted methodunu çalıştır. İşin bitince de yine TaskListener interface ni implement eden onTaskFinished methodunu çalıştır. 

Son olarak, taskımızı çalıştıracağımız sınıf içerisine geliyoruz ve bu kodları yazıyoruz. [code]AsyncTask mytask = new MyAsyncTask(this);

mytask.execute(); [/code]

Bu koddaki en önemli nokta, AsyncTask sınıfının almış olduğu TaskListener tipindeki argüman. Yani, sen çalış ama işlemlerin sonucunu da buraya gönder diyoruz. Şimdi yapmanız gereken tek şey, TaskListener interfaceni implemen ettiğin sınıftaki onTaskStarted methodu altında dialog pencereni göstermen ve onTaskFinished() methodu altında da dialog pencereni gizlemen..

Bu aslında pure javadır. Onun için java bilmedne android çalışmayın.. zorlanırsınız..

 

Zafer Celaloglu
07.11.2014 - 01:46
Burada pattern kullanmış oluyorsun o zaman kendi içerisinde dialog yaratmak yerine implements ettiriyorsun
Baran BÜYÜK
07.11.2014 - 02:47
Daha esnek bir yapı.. Bu nedenle bu yapıyı kullanmak avantajlı.. Fakat, tabiki de AsyncTask sınıfı içerisinde de kullanabilirdi.. Bu yapının en önemli özelliği, döndürülen sonucun (bu bir list, map veya setten türemiş nesne olabilir) istediğin sınıfa çok rahatlıkla gönderebiliyorsun.. Yani, kısacası AsyncTask sınıfını işlem yapan activity'den ayırıyorsun..
Caner Güral
07.11.2014 - 03:15
güzel yanıt.
picture-5943-1383435594.jpg
zafer.celaloglu
06.11.2014 - 09:14

NPE alıyosun buda bir nesneyi yaratmadan kullandığına işarettir.Dikkat edersen logta çok açık bir şekilde anlatmış:

info.androidhive.slidingmenu.WhatsHotFragment$myAsyncTask.onPreExecute(WhatsHotFragment.java:91) 

Burada Dialog koşturuyosun ama bunu New anahtar kelimesi ile initialize etmemişsin önce yaratacaksın sonra onu onPreExecute() içerisinde kullanacaksın bundan dolayı

//  this.dialog = new ProgressDialog(); bu kapalı kodu aç :)

turgay
06.11.2014 - 09:56
aslında daha önce bu kod satırı açıktı. hatta şöyle idi this.dialog = new ProgressDialog(this); fakat bu şekilde çalışmadı bende this.dialog = new ProgressDialog(view.this); dedim. bu şekilde de web service ten cevap gelmeden uygulamayı kapatıp çıkıyor program. inanır mısınız bilmiyorum 3 gündür bununla uğraşıyorum. nette bir tane örnek bulamadım.
Zafer Celaloglu
06.11.2014 - 11:34
Peki o kodu onPreExecute içine taşı ardından hata alırsan logu paylaş info.androidhive.slidingmenu.WhatsHotFragment.onClick(WhatsHotFragment.java:68) Aynı zamanda seni bu satırda da uyarıyor ona da dikkat et onClick içerisinde New ile yaratırken birde "Yükleniyor" sil
turgay
06.11.2014 - 11:42
pekala denedikten sonra sizlerle paylaşırım. eğer bu çalışmayı tamamlayabilirsek hepsini buradan paylaşırım belki birilerinin işine yarayabilir. fakat dediğiniz kod hangisi ? onPreExecute içine public myAsyncTask(String mMesaj) { this.modalMesaj = mMesaj; this.dialog = new ProgressDialog(view.this); } bu kodu nasıl taşıyabilirim. veya butona tıklamadan AsyncTask ı nasıl tetikleyebilirim?
Zafer Celaloglu
06.11.2014 - 11:52
Sana tavsiyem böyle complex bir kodla boğuşman yerine temelleri üzerinde pratik yapman hatta Java üzerinde belli seviyeye gelmeden bodozlama buraya daldıysan önce bir JAVA yı ögrenip ardından Android e geçiş yapman iyi çalışmalar...
turgay
06.11.2014 - 01:25
evet biraz bodoslama daldım ama öncesinde şunu belirteyim yaklaşık 3 senedir c# ile program yazmaktayım. şu an bir devlet kurumunda oracle dba jr. olarak görev yapıyorum. (3 sene de böyle ve buna ek olarak oracle forms and reports developer, aynı zamanda Oracle BI da var tabi), bundan da önce basic, C, C++, delphi ile program yazdım ama dediğin gibi java biraz daha farklı. yani kodları çözerek buraya kadar geldim. bir de şu var tabi basit düzeyle başlamak iyi ama esaslı bir projede kavrulmak benim için daha öğretici oluyor. belki siz biliyorsunuzdur bu konuları ama kusura bakmayın pek yardımcı olmuyorsunuz. yine de teşekkürler.
Zafer Celaloglu
06.11.2014 - 01:49
Tamam ama bunu kullanmadan önce AsynTask nedir override edilmesi gereken methodları hangileridir hangi method ne yapar diye araştırman lazım ki milyonlarca türkçe-ingilizce döküman var muhakkak öğrenirsin.2. olarak ise normalde burada cevap yazmıyordum aktif olarak dün başladım hem sormaya hem de elimden geldiği kadar cevap vermeye yardımcı olmuyorsun dersen bu biraz nankörce yaklaşım olur. Herneyse ben gene yardımcı olmaya çalışıyım Fragment konusuna biraz bak hangi methodları ne yapar life cycle i nedir benim bildiğim kadarıyla onStart methodunu override edip new myAsyncTask().execute(); içerisinde koşturabilirsin.Daha önceden dediğim gibi logcat onPreExecute üzerinde NPE döndürüyor bu yüzden this.dialog = new ProgressDialog(); bunu onPreExecute içerisinde en başa al (dialog.setMessage(modalMesaj); dialog.setIndeterminate(true); dialog.setCancelable(false); dialog.show(); ) bunlardan önce yaz.
turgay
06.11.2014 - 02:02
peki çok teşekkür ederim zafer, aslına bakarsan bu methodu çalıştırdım. yaptığım internet sitelerinden birinde bir veri tabanım var, oradan asp.net ile veriyi çekiyorum fakat bu fragment i ekleyince hata vermeye başladı maalesef. bu arada yardımcı olmuyorsun derken biliyorsun ama yazmıyorsun sanmıştım. kusura bakma ve bu arada araştırma yaptım. ingilizce - türkçe kaynaklara da baktım. maalesef fragment altında çalışan örnekler deki gibi hepsi çalışıyor ama bu çalışmıyor :) neyse araştırmaya devam.
turgay
06.11.2014 - 02:02
peki çok teşekkür ederim zafer, aslına bakarsan bu methodu çalıştırdım. yaptığım internet sitelerinden birinde bir veri tabanım var, oradan asp.net ile veriyi çekiyorum fakat bu fragment i ekleyince hata vermeye başladı maalesef. bu arada yardımcı olmuyorsun derken biliyorsun ama yazmıyorsun sanmıştım. kusura bakma ve bu arada araştırma yaptım. ingilizce - türkçe kaynaklara da baktım. maalesef fragment altında çalışan örnekler deki gibi hepsi çalışıyor ama bu çalışmıyor :) neyse araştırmaya devam.
Zafer Celaloglu
06.11.2014 - 02:50
Bende şu an kendi uygulamamı yazıyorum ondan dolayı AsynTask ile 2 farklı Fragment classım var bu yüzden yardımcı olabileceğimi düşündüm.Bende bazen çok takılıyorum araştırmadığım yer kalmıyor pes etme noktasına geliyorum ama önemli olan pes etmeden devam etmek bende Fragment ile ilgili çok birşey bilmiyordum bu uygulama sayesinde baya araştırma fırsatım oldu.AysnTask background işlemlerini handle ettiği için dikkatli implement etmek şart.Logcat 2 hata gösteriyor bunlara yogunlaş info.androidhive.slidingmenu.WhatsHotFragment$myAsyncTask.onPreExecute(WhatsHotFragment.java:91) info.androidhive.slidingmenu.WhatsHotFragment.onClick(WhatsHotFragment.java:68)
turgay
06.11.2014 - 03:05
teşekkür ederim zafer senin de dediğin gibi pes etmek yok kolay gelsin.
picture-9388-1408276089.png
tahakirca
06.11.2014 - 07:11

new myAsyncTask("Yükleniyor").execute(); içindeki string değeri olmadan göndermeyi denedi mi?

new myAsyncTask().execute(); şeklinde deneyip mesajı içerde oluşturmayı denesene bakalaım bir etkisi oluyor mu?

turgay
06.11.2014 - 08:48
maalesef boş olarak kabul etmedi.
picture-5943-1383435594.jpg
zafer.celaloglu
05.11.2014 - 10:16

Bu sekilde kod paylasmak yerine LOG paylasman daha mantikli ayni sekilde senin nerede hata oldugunu gormen icin LOGCAT icerisindeki bilgilendirmeleri iyi okuman gerekli hangi classin kacinci satirinda hata var bunun nedeni ne orada net olarak yazar.

turgay
05.11.2014 - 10:52
haklısınız ama logcat i durduramıyorum ve hiç anlamlı hata vermiyor.
turgay
05.11.2014 - 10:58
11-05 22:54:23.775: E/AndroidRuntime(2928): FATAL EXCEPTION: main 11-05 22:54:23.775: E/AndroidRuntime(2928): java.lang.NullPointerException 11-05 22:54:23.775: E/AndroidRuntime(2928): at info.androidhive.slidingmenu.WhatsHotFragment$myAsyncTask.onPreExecute(WhatsHotFragment.java:91) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.os.AsyncTask.execute(AsyncTask.java:534) 11-05 22:54:23.775: E/AndroidRuntime(2928): at info.androidhive.slidingmenu.WhatsHotFragment.onClick(WhatsHotFragment.java:68) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.view.View.performClick(View.java:4211) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.view.View$PerformClick.run(View.java:17446) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.os.Handler.handleCallback(Handler.java:725) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.os.Handler.dispatchMessage(Handler.java:92) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.os.Looper.loop(Looper.java:153) 11-05 22:54:23.775: E/AndroidRuntime(2928): at android.app.ActivityThread.main(ActivityThread.java:5336) 11-05 22:54:23.775: E/AndroidRuntime(2928): at java.lang.reflect.Method.invokeNative(Native Method) 11-05 22:54:23.775: E/AndroidRuntime(2928): at java.lang.reflect.Method.invoke(Method.java:511) 11-05 22:54:23.775: E/AndroidRuntime(2928): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833) 11-05 22:54:23.775: E/AndroidRuntime(2928): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 11-05 22:54:23.775: E/AndroidRuntime(2928): at dalvik.system.NativeStart.main(Native Method)